package com.example.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import springfox.documentation.oas.annotations.EnableOpenApi;


/**
 * SpringBoot启动加载顺序
 * 1 启动准备阶段
 *   1.1 装载核心启动器类：org.springframework.boot.SpringApplication
 *   1.2 通过构造函数创建SpringApplication实例时，进行一系列的初始化工作，包括：
 *      1.2.1 判断并设置web环境类型（如SERVLET、REACTIVE等）。
 *      1.2.2 使用SpringFactoriesLoader加载ApplicationContextInitializer和ApplicationListener。
 *      1.2.3 推断并设置主配置类（primary sources）。
 * 2 配置加载阶段
 *   2.1 Spring Boot项目会按照特定的顺序加载配置文件，这些配置文件可以是application.properties或application.yml格式。
 *   2.2 配置文件的加载顺序（优先级由高到低）：
 *       file:./config/（项目根路径下的config文件夹）
 *       file:./（项目根路径）
 *       classpath:/config/（类路径下的config文件夹）
 *       classpath:/（类路径）
 *   2.3 外部配置文件的加载方式：
 *       命令行参数：可以直接在启动命令后添加启动参数。
 *       spring.config.location：用于指定配置文件的新位置。
 *       如果多个文件有相同的key，高优先级的值会覆盖低优先级的值。
 * 3 上下文准备阶段
 *   3.1 准备并刷新应用上下文（Context）。
 *   3.2 加载所有的初始化器（如从META-INF/spring.factories配置文件中加载的）。
 *   3.3 加载所有的监听器（也是从META-INF/spring.factories配置文件中加载的）。
 * 4 启动执行阶段
 *   4.1 触发所有CommandLineRunner执行。
 *   4.2 执行自定义的初始化逻辑（如果有的话）。
 * 5 完成阶段
 *   5.1启动完成，等待退出。
 *
 * 带profile的配置文件（如application-dev.yml）通常具有比不带profile的配置文件（如application.yml）更高的优先级。
 * 如果使用Spring Boot的自动配置机制，那么会有一系列自动配置类根据条件进行加载和配置。
 * 具体的启动加载顺序可能会因Spring Boot版本和具体配置而有所不同，但整体流程是类似的。
 */

@EnableFeignClients
@EnableOpenApi
@SpringBootApplication
@EnableDiscoveryClient
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}
